package com.zm.admin.zmeng.controller;


import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zm.admin.annotation.SysLogTag;
import com.zm.admin.zmeng.domain.*;
import com.zm.admin.zmeng.dto.OrgAllDTO;
import com.zm.admin.zmeng.dto.UserDto;
import com.zm.admin.zmeng.mapper.*;
import com.zm.admin.zmeng.service.ZmAttachmentService;
import com.zm.admin.zmeng.service.ZmUserService;
import com.zm.admin.utils.ResultBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 *
 * @Auther: MuYun
 * @Date: 2022/6/29 22:19
 * @Description： 用户相关接口
 *
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private static Logger logger= LoggerFactory.getLogger(LoginController.class);

    @Resource
    private ZmUserMapper zmUserMapper;

    @Resource
    private ZmOrgMapper zmOrgMapper;

    @Resource
    private ZmRoleMapper zmRoleMapper;

    @Resource
    private ZmMenuMapper zmMenuMapper;

    @Resource
    private ZmUserOrgMapper zmUserOrgMapper;

    @Resource
    private ZmUserRoleMapper zmUserRoleMapper;

    @Resource
    private ZmUserService zmUserService;

    @Resource
    private ZmAttachmentService zmAttachmentService;

    /**
     * 用户excel导出
     * @param response
     */
    @RequestMapping("/export")
    @ResponseBody
    @SysLogTag(desc = "excel导出")
    public ResultBean export(HttpServletResponse response){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmUser> wrapper=new QueryWrapper<>();
        ExcelWriter writer =null;
        try {
            wrapper.lambda().ge(ZmUser::getStatus, "0");
            //不查id,密码，盐值，头像（因为是路径地址
            wrapper.select(ZmUser.class,i->!"id".equals(i.getColumn()));
            wrapper.select(ZmUser.class,i->!"password".equals(i.getColumn()));
            wrapper.select(ZmUser.class,i->!"salt".equals(i.getColumn()));
            wrapper.select(ZmUser.class,i->!"image".equals(i.getColumn()));
            List<ZmUser> zmUserList = zmUserMapper.selectList(wrapper);
            if(zmUserList.size()!=0){
                //组装文件名
                SimpleDateFormat format=new SimpleDateFormat("yyyyMMdd");
                String time=format.format(new Date());
                String newFilename=time+new Random().nextInt(10000)+ ".xls";
                // 通过工具类创建writer，默认创建xls格式
                writer = ExcelUtil.getWriter();
                writer.addHeaderAlias("id", "编号");
                writer.addHeaderAlias("username", "用户名");
                writer.addHeaderAlias("sex", "性别");
                writer.addHeaderAlias("email", "邮箱");
                writer.addHeaderAlias("status", "状态");
                writer.addHeaderAlias("loginIp", "上次登陆IP");
                //借用，不然重新赋值进去还是Date格式，excel乱码
                writer.addHeaderAlias("password", "用户创建时间");
                writer.addHeaderAlias("salt", "上次修改时间");
                // 合并8个单元格后的标题行，使用默认标题样式
                writer.merge(7, "用户基础信息");
                int index=0;
                Iterator<ZmUser> iterator = zmUserList.iterator();
                while(iterator.hasNext()){
                    ZmUser user=iterator.next();
                    int i=index+1;
                    //变化
                    user.setId(Integer.toString(i));
                    index++;
                    //状态改造
                    if("1".equals(user.getStatus())){
                        user.setStatus("启用");
                    }else if("-1".equals(user.getStatus())) {
                        iterator.remove();
                    }else {
                        user.setStatus("禁用");
                    }
                    SimpleDateFormat format1=new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    user.setPassword(format1.format(user.getCreateTime()));
                    //可能没修改过
                    if(ObjectUtil.isNotEmpty(user.getUpdateTime())){
                        user.setSalt(format1.format(user.getCreateTime()));
                    }else{
                        user.setSalt("");
                    }
            }
                writer.setOnlyAlias(true);
                // 写到excel，使用默认样式，强制输出标题
                writer.write(zmUserList, true);
                //response为HttpServletResponse对象
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                ServletOutputStream out=response.getOutputStream();
                //out为OutputStream，需要写出到的目标流
                writer.flush(out);
                resultBean.setCode(ResultBean.CODE_SUCCESS);
            }
        }catch (Exception e){
            logger.info("导出用户excel接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);

        }finally {
            // 关闭writer，释放内存
            writer.close();
        }
        return resultBean;
    }

    /**
     * 头像上传
     * @param request
     * @param file
     * @return
     */
    @RequestMapping("/imgUpload")
    @SysLogTag(desc = "上传头像")
    public ResultBean imgUpload(HttpServletRequest request, MultipartFile file){
        ResultBean resultBean=new ResultBean();
        try{
            String urlPath = zmAttachmentService.upload(request, file, "用户上传头像");
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(urlPath);
        }catch (Exception e){
            logger.info("{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }
        return resultBean;
    }

    /**
     * 根据用户id获取其对应组织和角色
     * @param id
     * @return
     */
    @RequestMapping(("/get"))
    @SysLogTag(desc = "查看用户详情")
    public ResultBean getUserOrgAndRole(@RequestParam(value = "id") String id){
        ResultBean resultBean=new ResultBean();
        if(ObjectUtil.isEmpty(id)){
            return resultBean.setCode(ResultBean.CODE_ERROR).setMsg("获取用户信息出错！");
        }
        Map<String, Object> map=new HashMap<>();
        try{
            ZmOrg zmOrg = zmOrgMapper.selectUserOrg(id);
            List<OrgAllDTO> orgAllDTOList = zmOrgMapper.selectOrgAll(zmOrg.getId(), "up");
            if(ObjectUtil.isNotEmpty(orgAllDTOList)){
                OrgAllDTO orgAll = orgAllDTOList.get(0);
                String pathname=orgAll.getFname()+"/"+orgAll.getSname()+"/"+orgAll.getHname();
                zmOrg.setPathname(pathname);
            }else{
                zmOrg.setPathname("没捕捉到捏");
            }
            ZmRole zmRole = zmRoleMapper.selectUserRole(id);
            map.put("org",zmOrg);
            map.put("role",zmRole);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(map).setMsg("查询成功");
        }catch (Exception e){
            logger.info("查询用户信息接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }
        return resultBean;
    }

    /**
     * 获取组织下的所有用户
     * @param userDto
     * @return
     */
    @RequestMapping("/list")
    public ResultBean getUserForOrg(UserDto userDto){
        ResultBean resultBean=new ResultBean();
        Integer pageNo=1;
        Integer pageSize=5;
        if(ObjectUtil.isNotEmpty(userDto.getPageNo())){
            pageNo=userDto.getPageNo();
        }
        if(ObjectUtil.isNotEmpty(userDto.getPageSize())){
            pageSize=userDto.getPageSize();
        }
        try{
            //这里写死查下级组织的，因为是点击组织树上叶子的接口
            String type="low";
            List<OrgAllDTO> orgAllList = zmOrgMapper.selectOrgAll(userDto.getOrgid(),type);
            HashSet<String> set=new HashSet();
            if(ObjectUtil.isNotEmpty(orgAllList)){
                for (OrgAllDTO all:orgAllList) {
                    if(StrUtil.isNotBlank(all.getFid())){
                    set.add(all.getFid());}
                    if(StrUtil.isNotBlank(all.getSid())){
                    set.add(all.getSid());}
                    if(StrUtil.isNotBlank(all.getHid())){
                    set.add(all.getHid());}
                }
                IPage<ZmUser> iPage=new Page<>(pageNo,pageSize);
                //分页+组织条件筛选
                List<ZmUser> zmUsers = zmOrgMapper.selectUserForOrg(iPage,set,userDto);
                for(ZmUser zmUser:zmUsers){
                    zmUser.setPassword(SaSecureUtil.aesDecrypt(zmUser.getSalt(),zmUser.getPassword()));
                }
                //logger.info("用户：{}",zmUsers);
                //这里不带分页去查下数据总量，带分页会限制总数
                int size=zmOrgMapper.selectUserForOrg(null,set,userDto).size();
                //logger.info("总数：{}",Long.parseLong(size));
                resultBean.setDataCount(Long.parseLong(Integer.toString(size))).setCode(ResultBean.CODE_SUCCESS).setData(zmUsers);
                //logger.info("结果集：{}",resultBean);
            }else {
                resultBean.setCode(ResultBean.CODE_SUCCESS);
            }
        }catch (Exception e){
            logger.info("获取组织对应用户出错：{}",e);
            return resultBean.setMsg(e.getMessage()).setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 获取所有启用的用户
     * @return
     */
    @RequestMapping(("/getAllUser"))
    public ResultBean getAllUser(){
        ResultBean resultBean=new ResultBean();
        try{
            QueryWrapper<ZmUser> wrapper=new QueryWrapper<>();
            List<ZmUser> zmUsers = zmUserMapper.selectList(wrapper.lambda().eq(ZmUser::getStatus, "1"));
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(zmUsers);
        }catch (Exception e){
            resultBean.setCode(ResultBean.CODE_ERROR);
            logger.error("获取所有启用的用户接口报错:{}",e);
        }
        return resultBean;
    }

    /**
     * 获取所有用户名
     * @return
     */
    @RequestMapping(("/getAllUsername"))
    public ResultBean getAllUsername(){
        ResultBean resultBean=new ResultBean();
        try{
            List<String> list = zmUserMapper.selectAllUsername();
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(list);
        }catch (Exception e){
            resultBean.setCode(ResultBean.CODE_ERROR);
            logger.error("获取所有用户名接口报错:{}",e);
        }
        return resultBean;
    }

    /**
     * 获取当前登录用户的权限信息
     * @return
     */
    @RequestMapping(("/getUserPermission"))
    public ResultBean getUserPermission(){
        ResultBean resultBean=new ResultBean();
        try{
            List<ZmMenu> zmMenus = zmMenuMapper.selectMenuByUserId(StpUtil.getLoginId().toString());
            List<String> permissionList=zmMenus.stream().map(ZmMenu::getPermission).collect(Collectors.toList());
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(permissionList);
        }catch (Exception e){
            resultBean.setCode(ResultBean.CODE_ERROR);
            logger.error("获取登录用户权限接口报错:{}",e);
        }
        return resultBean;
    }

    /**
     * 修改用户基本信息与组织、角色对应关系
     * @param user
     * @return
     */
    @PostMapping("/update")
    @SysLogTag(desc = "修改用户")
    public ResultBean update(ZmUser user){
        ResultBean resultBean=new ResultBean();
        //logger.info("参数：{}",user);
        if(ObjectUtil.isEmpty(user)){
            return resultBean.setCode(ResultBean.CODE_ERROR).setMsg("删除用户出错！");
        }
        try{
            user.setUpdateTime(DateUtil.date());
            user.setPassword(SaSecureUtil.aesEncrypt(user.getSalt(),user.getPassword()));
            zmUserMapper.updateById(user);
            zmUserService.updateUserOrgAndRole(user);
        }catch (Exception e){
            logger.info("操作用户接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }
        return resultBean.setCode(ResultBean.CODE_SUCCESS);
    }

    /**
     * 修改用户基本信息与组织、角色对应关系
     * @param user
     * @return
     */
    @PostMapping("/del")
    @SysLogTag(desc = "删除用户")
    public ResultBean del(ZmUser user){
        ResultBean resultBean=new ResultBean();
        //logger.info("参数：{}",user);
        if(ObjectUtil.isEmpty(user)){
            //假删除
            return resultBean.setCode(ResultBean.CODE_ERROR).setMsg("删除用户出错！");
        }
        try{
            user.setStatus("-1");
            user.setUpdateTime(DateUtil.date());
            zmUserMapper.updateById(user);
            zmUserService.updateUserOrgAndRole(user);
        }catch (Exception e){
            logger.info("操作用户接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }
        return resultBean.setCode(ResultBean.CODE_SUCCESS).setMsg("删除成功");
    }

    /**
     * 批量删除用户
     * @param list
     * @return
     */
    @PostMapping("/batchDel")
    @SysLogTag(desc = "批量删除用户")
    public ResultBean batchDel(@RequestBody List<ZmUser> list){
        ResultBean resultBean=new ResultBean();
        try{
           for(ZmUser zmUser:list){
               zmUser.setStatus("-1");
               zmUserMapper.updateById(zmUser);
           }
        }catch (Exception e){
            logger.info("批量删除用户接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }

        return resultBean.setCode(ResultBean.CODE_SUCCESS);
    }

    /**
     * 新增用户
     * @param user
     * @return
     */
    @PostMapping("/add")
    @SysLogTag(desc = "新增用户")
    public ResultBean add(ZmUser user){
        ResultBean resultBean=new ResultBean();
        try{
            user.setIntroduce("嘘，我们别告诉他还有个人简介没填0.0");
            QueryWrapper<ZmUser> wrapper=new QueryWrapper<>();
            ZmUser zmUser = zmUserMapper.selectOne(wrapper.lambda().eq(ZmUser::getUsername, user.getUsername()));
            if(ObjectUtil.isNotEmpty(zmUser)){
                return resultBean.setCode(ResultBean.CODE_WARNING);
            }
            user.setCreateTime(DateUtil.date());
            //新增用户
            zmUserMapper.insert(user);
            if(StrUtil.isNotEmpty(user.getOrgid())){
                //新增用户组织关系
                ZmUserOrg zmUserOrg =new ZmUserOrg();
                zmUserOrg.setUserId(user.getId().toString());
                zmUserOrg.setOrgId(user.getOrgid());
                zmUserOrg.setCreateTime(DateUtil.date());
                zmUserOrgMapper.insert(zmUserOrg);
            }
            if(StrUtil.isEmpty(user.getRoleid())){
                user.setRoleid("3");
            }
            //新增用户角色关系
            ZmUserRole zmUserRole=new ZmUserRole();
            zmUserRole.setUserId(user.getId().toString());
            zmUserRole.setRoleId(user.getRoleid());
            zmUserRole.setCreateTime(DateUtil.date());
            zmUserRoleMapper.insert(zmUserRole);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setMsg("添加成功");
        }catch (Exception e){
            logger.info("{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    //获取所有用户信息，目前废弃
    /*@PostMapping("/getUserList")
    public ResultBean getUserList(){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmUser> wrapper=new QueryWrapper<>();
        try{
            List<ZmUser> zmUserList = zmUserMapper.selectList(wrapper.lambda().ge(ZmUser::getStatus, "0"));
            Long dataCount = (long) zmUserList.size();
            for (ZmUser user:zmUserList){
                logger.info("用户信息：{}",user);
            }
            resultBean.setData(zmUserList).setCode(ResultBean.CODE_SUCCESS).setMsg("查询成功").setdataCount(dataCount);
        }catch (Exception e){
            logger.info("查询用户集合接口异常：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
            return resultBean;
        }
        return resultBean;
    }*/

}
